From: Penny Zheng Date: Thu, 8 Sep 2022 13:55:09 +0000 (+0800) Subject: xen/arm: Add additional reference to owner domain when the owner is allocated X-Git-Tag: archive/raspbian/4.17.0-1+rpi1^2~33^2~200 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https://%22%22/%22http:/www.example.com/cgi/%22https:/%22%22?a=commitdiff_plain;h=041957bad382ba0a393164e8530aa66eacbbb8a3;p=xen.git xen/arm: Add additional reference to owner domain when the owner is allocated Borrower domain will fail to get a page ref using the owner domain during allocation, when the owner is created after borrower. So here, we decide to get and add the right amount of reference, which is the number of borrowers, when the owner is allocated. Signed-off-by: Penny Zheng Reviewed-by: Stefano Stabellini Acked-by: Julien Grall --- diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index c6c6c942d8..417a0e82ba 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -763,6 +763,30 @@ static void __init assign_static_memory_11(struct domain *d, } #ifdef CONFIG_STATIC_SHM +static int __init acquire_nr_borrower_domain(struct domain *d, + paddr_t pbase, paddr_t psize, + unsigned long *nr_borrowers) +{ + unsigned int bank; + + /* Iterate reserved memory to find requested shm bank. */ + for ( bank = 0 ; bank < bootinfo.reserved_mem.nr_banks; bank++ ) + { + paddr_t bank_start = bootinfo.reserved_mem.bank[bank].start; + paddr_t bank_size = bootinfo.reserved_mem.bank[bank].size; + + if ( (pbase == bank_start) && (psize == bank_size) ) + break; + } + + if ( bank == bootinfo.reserved_mem.nr_banks ) + return -ENOENT; + + *nr_borrowers = bootinfo.reserved_mem.bank[bank].nr_shm_borrowers; + + return 0; +} + /* * This function checks whether the static shared memory region is * already allocated to dom_io. @@ -829,6 +853,8 @@ static int __init assign_shared_memory(struct domain *d, { mfn_t smfn; int ret = 0; + unsigned long nr_pages, nr_borrowers, i; + struct page_info *page; dprintk(XENLOG_INFO, "%pd: allocate static shared memory BANK %#"PRIpaddr"-%#"PRIpaddr".\n", @@ -842,6 +868,7 @@ static int __init assign_shared_memory(struct domain *d, * DOMID_IO is not auto-translated (i.e. it sees RAM 1:1). So we do not need * to create mapping in the P2M. */ + nr_pages = PFN_DOWN(psize); if ( d != dom_io ) { ret = guest_physmap_add_pages(d, gaddr_to_gfn(gbase), smfn, @@ -853,6 +880,39 @@ static int __init assign_shared_memory(struct domain *d, } } + /* + * Get the right amount of references per page, which is the number of + * borrower domains. + */ + ret = acquire_nr_borrower_domain(d, pbase, psize, &nr_borrowers); + if ( ret ) + return ret; + + /* + * Instead of letting borrower domain get a page ref, we add as many + * additional reference as the number of borrowers when the owner + * is allocated, since there is a chance that owner is created + * after borrower. + * So if the borrower is created first, it will cause adding pages + * in the P2M without reference. + */ + page = mfn_to_page(smfn); + for ( i = 0; i < nr_pages; i++ ) + { + if ( !get_page_nr(page + i, d, nr_borrowers) ) + { + printk(XENLOG_ERR + "Failed to add %lu references to page %"PRI_mfn".\n", + nr_borrowers, mfn_x(smfn) + i); + goto fail; + } + } + + return 0; + + fail: + while ( --i >= 0 ) + put_page_nr(page + i, nr_borrowers); return ret; }